home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / idlelib / ClassBrowser.py < prev    next >
Text File  |  2005-10-18  |  6KB  |  222 lines

  1. """Class browser.
  2.  
  3. XXX TO DO:
  4.  
  5. - reparse when source changed (maybe just a button would be OK?)
  6.     (or recheck on window popup)
  7. - add popup menu with more options (e.g. doc strings, base classes, imports)
  8. - show function argument list? (have to do pattern matching on source)
  9. - should the classes and methods lists also be in the module's menu bar?
  10. - add base classes to class browser tree
  11. """
  12.  
  13. import os
  14. import sys
  15. import pyclbr
  16.  
  17. import PyShell
  18. from WindowList import ListedToplevel
  19. from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
  20. from configHandler import idleConf
  21.  
  22. class ClassBrowser:
  23.  
  24.     def __init__(self, flist, name, path):
  25.         # XXX This API should change, if the file doesn't end in ".py"
  26.         # XXX the code here is bogus!
  27.         self.name = name
  28.         self.file = os.path.join(path[0], self.name + ".py")
  29.         self.init(flist)
  30.  
  31.     def close(self, event=None):
  32.         self.top.destroy()
  33.         self.node.destroy()
  34.  
  35.     def init(self, flist):
  36.         self.flist = flist
  37.         # reset pyclbr
  38.         pyclbr._modules.clear()
  39.         # create top
  40.         self.top = top = ListedToplevel(flist.root)
  41.         top.protocol("WM_DELETE_WINDOW", self.close)
  42.         top.bind("<Escape>", self.close)
  43.         self.settitle()
  44.         top.focus_set()
  45.         # create scrolled canvas
  46.         theme = idleConf.GetOption('main','Theme','name')
  47.         background = idleConf.GetHighlight(theme, 'normal')['background']
  48.         sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1)
  49.         sc.frame.pack(expand=1, fill="both")
  50.         item = self.rootnode()
  51.         self.node = node = TreeNode(sc.canvas, None, item)
  52.         node.update()
  53.         node.expand()
  54.  
  55.     def settitle(self):
  56.         self.top.wm_title("Class Browser - " + self.name)
  57.         self.top.wm_iconname("Class Browser")
  58.  
  59.     def rootnode(self):
  60.         return ModuleBrowserTreeItem(self.file)
  61.  
  62. class ModuleBrowserTreeItem(TreeItem):
  63.  
  64.     def __init__(self, file):
  65.         self.file = file
  66.  
  67.     def GetText(self):
  68.         return os.path.basename(self.file)
  69.  
  70.     def GetIconName(self):
  71.         return "python"
  72.  
  73.     def GetSubList(self):
  74.         sublist = []
  75.         for name in self.listclasses():
  76.             item = ClassBrowserTreeItem(name, self.classes, self.file)
  77.             sublist.append(item)
  78.         return sublist
  79.  
  80.     def OnDoubleClick(self):
  81.         if os.path.normcase(self.file[-3:]) != ".py":
  82.             return
  83.         if not os.path.exists(self.file):
  84.             return
  85.         PyShell.flist.open(self.file)
  86.  
  87.     def IsExpandable(self):
  88.         return os.path.normcase(self.file[-3:]) == ".py"
  89.  
  90.     def listclasses(self):
  91.         dir, file = os.path.split(self.file)
  92.         name, ext = os.path.splitext(file)
  93.         if os.path.normcase(ext) != ".py":
  94.             return []
  95.         try:
  96.             dict = pyclbr.readmodule_ex(name, [dir] + sys.path)
  97.         except ImportError, msg:
  98.             return []
  99.         items = []
  100.         self.classes = {}
  101.         for key, cl in dict.items():
  102.             if cl.module == name:
  103.                 s = key
  104.                 if hasattr(cl, 'super') and cl.super:
  105.                     supers = []
  106.                     for sup in cl.super:
  107.                         if type(sup) is type(''):
  108.                             sname = sup
  109.                         else:
  110.                             sname = sup.name
  111.                             if sup.module != cl.module:
  112.                                 sname = "%s.%s" % (sup.module, sname)
  113.                         supers.append(sname)
  114.                     s = s + "(%s)" % ", ".join(supers)
  115.                 items.append((cl.lineno, s))
  116.                 self.classes[s] = cl
  117.         items.sort()
  118.         list = []
  119.         for item, s in items:
  120.             list.append(s)
  121.         return list
  122.  
  123. class ClassBrowserTreeItem(TreeItem):
  124.  
  125.     def __init__(self, name, classes, file):
  126.         self.name = name
  127.         self.classes = classes
  128.         self.file = file
  129.         try:
  130.             self.cl = self.classes[self.name]
  131.         except (IndexError, KeyError):
  132.             self.cl = None
  133.         self.isfunction = isinstance(self.cl, pyclbr.Function)
  134.  
  135.     def GetText(self):
  136.         if self.isfunction:
  137.             return "def " + self.name + "(...)"
  138.         else:
  139.             return "class " + self.name
  140.  
  141.     def GetIconName(self):
  142.         if self.isfunction:
  143.             return "python"
  144.         else:
  145.             return "folder"
  146.  
  147.     def IsExpandable(self):
  148.         if self.cl:
  149.             try:
  150.                 return not not self.cl.methods
  151.             except AttributeError:
  152.                 return False
  153.  
  154.     def GetSubList(self):
  155.         if not self.cl:
  156.             return []
  157.         sublist = []
  158.         for name in self.listmethods():
  159.             item = MethodBrowserTreeItem(name, self.cl, self.file)
  160.             sublist.append(item)
  161.         return sublist
  162.  
  163.     def OnDoubleClick(self):
  164.         if not os.path.exists(self.file):
  165.             return
  166.         edit = PyShell.flist.open(self.file)
  167.         if hasattr(self.cl, 'lineno'):
  168.             lineno = self.cl.lineno
  169.             edit.gotoline(lineno)
  170.  
  171.     def listmethods(self):
  172.         if not self.cl:
  173.             return []
  174.         items = []
  175.         for name, lineno in self.cl.methods.items():
  176.             items.append((lineno, name))
  177.         items.sort()
  178.         list = []
  179.         for item, name in items:
  180.             list.append(name)
  181.         return list
  182.  
  183. class MethodBrowserTreeItem(TreeItem):
  184.  
  185.     def __init__(self, name, cl, file):
  186.         self.name = name
  187.         self.cl = cl
  188.         self.file = file
  189.  
  190.     def GetText(self):
  191.         return "def " + self.name + "(...)"
  192.  
  193.     def GetIconName(self):
  194.         return "python" # XXX
  195.  
  196.     def IsExpandable(self):
  197.         return 0
  198.  
  199.     def OnDoubleClick(self):
  200.         if not os.path.exists(self.file):
  201.             return
  202.         edit = PyShell.flist.open(self.file)
  203.         edit.gotoline(self.cl.methods[self.name])
  204.  
  205. def main():
  206.     try:
  207.         file = __file__
  208.     except NameError:
  209.         file = sys.argv[0]
  210.         if sys.argv[1:]:
  211.             file = sys.argv[1]
  212.         else:
  213.             file = sys.argv[0]
  214.     dir, file = os.path.split(file)
  215.     name = os.path.splitext(file)[0]
  216.     ClassBrowser(PyShell.flist, name, [dir])
  217.     if sys.stdin is sys.__stdin__:
  218.         mainloop()
  219.  
  220. if __name__ == "__main__":
  221.     main()
  222.